Skip to content

WPB-22970: migrate activation-keys to PostGreSQL - #5417

Open
blackheaven wants to merge 2 commits into
developfrom
gdifolco/WPB-22970-migration-postgres-activation-keys
Open

WPB-22970: migrate activation-keys to PostGreSQL#5417
blackheaven wants to merge 2 commits into
developfrom
gdifolco/WPB-22970-migration-postgres-activation-keys

Conversation

@blackheaven

Copy link
Copy Markdown
Contributor

https://wearezeta.atlassian.net/browse/WPB-22970

Checklist

  • Add a new entry in an appropriate subdirectory of changelog.d
  • Read and follow the PR guidelines

@blackheaven
blackheaven requested review from a team as code owners August 4, 2026 18:10

@akshaymankar akshaymankar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the expired codes somehow automatically get cleaned up from postgres? I couldn't see anything like that. Perhaps we should run a scheduled job to clean them up nightly or something.

Comment thread libs/wire-subsystems/postgres-migrations/20260804165620-activation-keys.sql Outdated
Comment on lines +12 to +14
-- index for lookups like `WHERE key = ? AND expires_at > now()`
CREATE INDEX activation_keys_key_expires_at_idx
ON activation_keys (key, expires_at);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this index needed if key is already the primary key?

Comment thread integration/test/Test/Migration/ActivationKeys.hs Outdated
Comment thread integration/test/Test/Migration/ActivationKeys.hs Outdated
Comment thread libs/wire-subsystems/src/Wire/ActivationCodeStore/Cassandra.hs Outdated
Add Postgres, DualWrite, and Migration interpreters for the
ActivationCodeStore effect (brig service). The migration follows the
canonical dual-write + background-worker pattern:

- Layer A: PostgresMarshall instances for ActivationKey/ActivationCode
- Layer B: Postgres interpreter with TTL鈫抏xpires_at conversion
- Layer C: DualWrite interpreter (reads鈫扖assandra, writes鈫抌oth)
- Layer D: Migration loop copying ttl(code)鈫抏xpires_at
- Layer E: activationKeys StorageLocation config field
- Layer F: Brig interpreter selection + second-writer refactor
- Layer G-H: Background-worker migration wrapper + flag
- Layer I-R: SQL migration, helm values, config docs, integration test

The key design decision: the second writer
(Brig.Data.Activation.verifyCode) that bypassed the effect is now routed
through a new VerifyActivationCode effect constructor. This preserves the
brute-force protection (3 max retries, TTL-preserving countdown, delete on
exhaustion) while allowing each interpreter to implement it natively.

ActivationCodeStore was moved before the Error block in
BrigLowerLevelEffects to ensure Error Hasql.UsageError is available when
the Postgres interpreter runs.

Bead: ws-migrate-postgresql-ec0
@blackheaven
blackheaven force-pushed the gdifolco/WPB-22970-migration-postgres-activation-keys branch from a8abee9 to b065da8 Compare August 27, 2026 14:05
@zebot zebot added the ok-to-test Approved for running tests in CI, overrides not-ok-to-test if both labels exist label Aug 27, 2026
@blackheaven
blackheaven force-pushed the gdifolco/WPB-22970-migration-postgres-activation-keys branch 2 times, most recently from 4cebe09 to ad3611f Compare August 27, 2026 16:53
- rename activation_keys column "user" -> user_id and drop the redundant
  (key, expires_at) index (PK on key serves the lookup); regenerate
  postgres-schema.sql
- move verification logic out of the ActivationCodeStore effect into a new
  Wire.ActivationCodeVerificationStore effect over the store; the store keeps
  persistence only (LookupActivationKey / DecrementActivationRetries /
  DeleteActivationKey)
- add a nightly Arbiter cron job (activation-keys queue) that deletes expired
  activation key rows from Postgres in bounded batches; new required config
  background-worker.config.activationKeysCleanup.schedule (default 0 3 * * *)
- rewrite the integration test to drive the full lifecycle
  cassandra -> dual-write -> dual-write+worker -> postgresql, including retry
  convergence and brute-force exhaustion
@blackheaven
blackheaven force-pushed the gdifolco/WPB-22970-migration-postgres-activation-keys branch from ad3611f to 9169072 Compare August 27, 2026 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test Approved for running tests in CI, overrides not-ok-to-test if both labels exist

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants